package com.zxmr.webclient.servlet;


import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.zxmr.action.Request;
import com.zxmr.action.RequestPayload;
import com.zxmr.action.Session;
import com.zxmr.domain.account.User;
import com.zxmr.domain.component.Component;
import com.zxmr.webclient.component.ComponentAsynRequest;
import com.zxmr.webclient.component.ComponentsRepository;

@SuppressWarnings("serial")
@WebServlet(asyncSupported=true)
public class ComponentDispatchServlet extends HttpServlet{

	DispatchExecutors executor = null;
	public ComponentDispatchServlet()
	{
		// temp 1 1 
		executor = new DispatchExecutors(1,1,30,500);
	}
	public void doGet(HttpServletRequest request,HttpServletResponse response)    
			throws ServletException, IOException 
	{
		AsyncContext aCtx = null;
		aCtx = request.startAsync(request, response); 
		aCtx.setTimeout(0);
		executor.execut(new Worker(aCtx,request));
		
	}
	
	class Worker implements Runnable{

		AsyncContext aCtx;
		HttpServletRequest request;
		
		public Worker(AsyncContext aCtx,HttpServletRequest request)
		{
			this.aCtx = aCtx;
			this.request = request;
		}
		@Override
		public void run() {
			try
			{
				String componentName = getComponentName(request);
				Component component = ComponentsRepository.getComponent(componentName);
				if(checkComponentAuthorize(component))
				{
					Request re = constructRequest(request,component);
					ComponentAsynRequest asynRequest = new ComponentAsynRequest(component,aCtx);
					
					asynRequest.setRequest(re);
					asynRequest.send();
				}else
				{
					aCtx.getResponse().getWriter().println("{\"result\":\"component is not authorized\"}");
					aCtx.complete();
				}

			}catch(Exception e)
			{
				e.printStackTrace();
				try {
					aCtx.getResponse().getWriter().println("{\"result\":\"internal error when dispatch the component request\"}");
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				aCtx.complete();
			}

			
		}
		
	}
	public boolean checkComponentAuthorize(Component component)
	{
		if(component == null)return false;
		return true;
	}
	public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {    
        doGet(request, response);
    }
	private String getComponentName(HttpServletRequest request)
	{
		String requestURL = request.getPathInfo();
		int secondSlash = requestURL.indexOf('/', 1);
		if(secondSlash < 0)secondSlash = requestURL.length();
		
		String component = requestURL.substring(1,secondSlash);
		if(component == null)component = "";
		
		System.out.println("component path is "+component);
		return component;
	}

	private String getRequestComponentPath(HttpServletRequest request,String componentName)
	{
		String componentPath = "/"+componentName;
		String url = request.getPathInfo();
		String result = url.substring(componentPath.length(), url.length());
		return result;
	}
	private Map<String,String> convertParameters(HttpServletRequest request)
	{
		Map<String,String> map = new HashMap<String,String>();
		Enumeration<String> em = request.getParameterNames();
		while(em.hasMoreElements())
		{
			String name = em.nextElement();
			String value = request.getParameter(name);
			map.put(name, value);
		}
		return map;
	}
	private Request constructRequest(HttpServletRequest request,Component component)
	{
		
		String componentPath = getRequestComponentPath(request,component.getName());
		
		Request re = new Request();
		Session se = new Session();
		se.setSessionID(request.getSession().getId());
		
		User employee = new User();
		employee.setName("yewenkuan");
		employee.setId(1);
		employee.setCompany(21);
		employee.setEmail("fdfd");
		
		re.setAccount(employee);
		re.setNeedResponse(true);
		re.setSession(se);
		
		RequestPayload payload  = new RequestPayload();
		payload.setUrl(componentPath);
		payload.setParameters(convertParameters(request));
		re.setPayload(payload);
		
		return re;
	}
}
